From 805c949b3493fcff6447f6bc797354510c53ca96 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 15 Dec 2006 09:38:56 +0000 Subject: [PATCH] [NET]: Fix segmentation of linear packets skb_segment fails to segment linear packets correctly because it tries to write all linear parts of the original skb into each segment. This will always panic as each segment only contains enough space for one MSS. This was not detected earlier because linear packets should be rare for GSO. In fact it still remains to be seen what exactly created the linear packets that triggered this bug. Basically the only time this should happen is if someone enables GSO emulation on an interface that does not support SG. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- linux-2.6-xen-sparse/net/core/skbuff.c | 9 +++---- .../net-gso-6-linear-segmentation.patch | 26 +++++++++++++++++++ patches/linux-2.6.16.33/series | 1 + 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch diff --git a/linux-2.6-xen-sparse/net/core/skbuff.c b/linux-2.6-xen-sparse/net/core/skbuff.c index 064e6277b1..5a524946b0 100644 --- a/linux-2.6-xen-sparse/net/core/skbuff.c +++ b/linux-2.6-xen-sparse/net/core/skbuff.c @@ -1875,7 +1875,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) do { struct sk_buff *nskb; skb_frag_t *frag; - int hsize, nsize; + int hsize; int k; int size; @@ -1886,11 +1886,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) hsize = skb_headlen(skb) - offset; if (hsize < 0) hsize = 0; - nsize = hsize + doffset; - if (nsize > len + doffset || !sg) - nsize = len + doffset; + if (hsize > len || !sg) + hsize = len; - nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); + nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); if (unlikely(!nskb)) goto err; diff --git a/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch new file mode 100644 index 0000000000..5e615a14a7 --- /dev/null +++ b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch @@ -0,0 +1,26 @@ +diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c +--- a/net/core/skbuff.c 2006-12-14 09:32:04 -08:00 ++++ b/net/core/skbuff.c 2006-12-14 09:32:04 -08:00 +@@ -1946,7 +1946,7 @@ + do { + struct sk_buff *nskb; + skb_frag_t *frag; +- int hsize, nsize; ++ int hsize; + int k; + int size; + +@@ -1957,11 +1957,10 @@ + hsize = skb_headlen(skb) - offset; + if (hsize < 0) + hsize = 0; +- nsize = hsize + doffset; +- if (nsize > len + doffset || !sg) +- nsize = len + doffset; ++ if (hsize > len || !sg) ++ hsize = len; + +- nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); ++ nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); + if (unlikely(!nskb)) + goto err; diff --git a/patches/linux-2.6.16.33/series b/patches/linux-2.6.16.33/series index 28fabf00ff..8410fb3bde 100644 --- a/patches/linux-2.6.16.33/series +++ b/patches/linux-2.6.16.33/series @@ -17,6 +17,7 @@ net-gso-2-checksum-fix.patch net-gso-3-fix-errorcheck.patch net-gso-4-kill-warnon.patch net-gso-5-rcv-mss.patch +net-gso-6-linear-segmentation.patch pci-mmconfig-fix-from-2.6.17.patch pmd-shared.patch rcu_needs_cpu.patch -- 2.30.2